/*
 * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
 *
 * SPDX-License-Identifier: MulanPSL-2.0
 */
#![allow(unused_variables)]
#![allow(unused_mut)]
#![allow(unused_imports)]
#![allow(unused_assignments)]
#![allow(unreachable_code)]
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(clashing_extern_declarations)]
#![allow(clippy::never_loop)]

use libc::exit;

#[macro_use]
mod common;

mod copy_file;
mod exec_common;
use common::*;
use copy_file::*;
use exec_common::*;

use stdext::function_name;

#[link(name = "utsudo_util")]
#[link(name = "util_variadic")]
extern "C" {
    fn utimensat(
        __fd: libc::c_int,
        __path: *const libc::c_char,
        __times: *const timespec,
        __flags: libc::c_int,
    ) -> libc::c_int;
    fn futimens(__fd: libc::c_int, __times: *const timespec) -> libc::c_int;
    fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void;
    fn sudo_copy_file(
        src: *const libc::c_char,
        src_fd: libc::c_int,
        src_len: off_t,
        dst: *const libc::c_char,
        dst_fd: libc::c_int,
        dst_len: off_t,
    ) -> libc::c_int;
    fn fstat(filedes:libc::c_int,buf:*mut stat) -> libc::c_int;
    fn geteuid() -> __uid_t;
    fn fcntl(__fd: libc::c_int, __cmd: libc::c_int, _: ...) -> libc::c_int;
    fn sudo_check_temp_file(
        tfd: libc::c_int,
        tname: *const libc::c_char,
        uid: uid_t,
        sb: *mut stat,
    ) -> bool;
    fn __errno_location() -> *mut libc::c_int;
    fn open(__file: *const libc::c_char, __oflag: libc::c_int, _: ...) -> libc::c_int;
    fn unlink(__name: *const libc::c_char) -> libc::c_int;
    fn close(__fd: libc::c_int) -> libc::c_int;
    fn _exit(_: libc::c_int) -> !;
    fn setlocale(__category: libc::c_int, __locale: *const libc::c_char) -> *mut libc::c_char;
    fn bindtextdomain(
        __domainname: *const libc::c_char,
        __dirname: *const libc::c_char,
    ) -> *mut libc::c_char;
    fn initprogname(_: *const libc::c_char);
    fn textdomain(__domainname: *const libc::c_char) -> *mut libc::c_char;
    fn sudo_warn_gettext_v1(
        domainname: *const libc::c_char,
        msgid: *const libc::c_char,
    ) -> *mut libc::c_char;
    fn sudo_fatalx_nodebug_v1(fmt: *const libc::c_char, _: ...) -> !;
    fn sudo_debug_printf2_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        level: libc::c_int,
        fmt: *const libc::c_char,
        _: ...
    );
    fn sudo_conf_read_v1(conf_file: *const libc::c_char, conf_types: libc::c_int) -> libc::c_int;
    fn sudo_debug_register_v1(
        program: *const libc::c_char,
        subsystems: *const *const libc::c_char,
        ids: *mut libc::c_uint,
        debug_files: *mut sudo_conf_debug_file_list,
    ) -> libc::c_int;
    fn sudo_getprogname() -> *const libc::c_char;
    fn sudo_conf_debug_files_v1(progname: *const libc::c_char) -> *mut sudo_conf_debug_file_list;
    fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
    fn strrchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char;
    fn strncmp(_: *const libc::c_char, _: *const libc::c_char, _: libc::c_ulong) -> libc::c_int;
    fn sudo_strtonum(
        _: *const libc::c_char,
        _: libc::c_longlong,
        _: libc::c_longlong,
        _: *mut *const libc::c_char,
    ) -> libc::c_longlong;
    fn strdup(_: *const libc::c_char) -> *mut libc::c_char;
    fn sudo_fatal_nodebug_v1(fmt: *const libc::c_char, _: ...) -> !;
    fn sudo_execve(
        fd: libc::c_int,
        path: *const libc::c_char,
        argv: *const *mut libc::c_char,
        envp: *mut *mut libc::c_char,
        noexec: bool,
    ) -> libc::c_int;
    fn sudo_debug_exit_int_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        subsys: libc::c_int,
        ret: libc::c_int,
    );
    fn sudo_warn_nodebug_v1(fmt: *const libc::c_char, _: ...);

}

//unsafe fn main_0(
fn main_0(
    mut argc: libc::c_int,
    mut argv: *mut *mut libc::c_char,
    mut envp: *mut *mut libc::c_char,
) -> libc::c_int {
    let mut ret: libc::c_int = 0;
    unsafe {
        sudo_debug_enter_v1(
            (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"main\0")).as_ptr(),
            b"sesh.c\0" as *const u8 as *const libc::c_char,
            70 as libc::c_int,
            sudo_debug_subsys,
        );
        initprogname(if argc > 0 as libc::c_int {
            *argv.offset(0 as libc::c_int as isize)
        } else {
            b"sesh\0" as *const u8 as *const libc::c_char
        });
        setlocale(6 as libc::c_int, b"\0" as *const u8 as *const libc::c_char);
        bindtextdomain(
            b"sudo\0" as *const u8 as *const libc::c_char,
            b"/usr/share/locale\0" as *const u8 as *const libc::c_char,
        );
        textdomain(b"sudo\0" as *const u8 as *const libc::c_char);
        if argc < 2 as libc::c_int {
            sudo_debug_printf2_v1(
                (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"main\0")).as_ptr(),
                b"sesh.c\0" as *const u8 as *const libc::c_char,
                79 as libc::c_int,
                2 as libc::c_int | (1 as libc::c_int) << 5 as libc::c_int | sudo_debug_subsys,
                sudo_warn_gettext_v1(
                    std::ptr::null::<libc::c_char>(),
                    b"requires at least one argument\0" as *const u8 as *const libc::c_char,
                ),
            );
            sudo_fatalx_nodebug_v1(sudo_warn_gettext_v1(
                std::ptr::null::<libc::c_char>(),
                b"requires at least one argument\0" as *const u8 as *const libc::c_char,
            ));
        }
        if sudo_conf_read_v1(std::ptr::null::<libc::c_char>(), 0x1 as libc::c_int)
            == -(1 as libc::c_int)
        {
            exit(1 as libc::c_int);
        }
        sudo_debug_register_v1(
            sudo_getprogname(),
            std::ptr::null::<*const libc::c_char>(),
            std::ptr::null_mut::<libc::c_uint>(),
            sudo_conf_debug_files_v1(sudo_getprogname()),
        );
        if strcmp(
            *argv.offset(1 as libc::c_int as isize),
            b"-e\0" as *const u8 as *const libc::c_char,
        ) == 0 as libc::c_int
        {
            ret = sesh_sudoedit(argc, argv);
        } else {
            let mut login_shell: bool = false;
            let mut noexec: bool = 0 as libc::c_int != 0;
            let mut cp: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
            let mut cmnd: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
            let mut fd: libc::c_int = -(1 as libc::c_int);
            login_shell = *(*argv.offset(0 as libc::c_int as isize))
                .offset(0 as libc::c_int as isize) as libc::c_int
                == '-' as i32;
            cp = strrchr(*argv.offset(0 as libc::c_int as isize), '-' as i32);
            if !cp.is_null() && cp != *argv.offset(0 as libc::c_int as isize) {
                noexec = strcmp(cp, b"-noexec\0" as *const u8 as *const libc::c_char)
                    == 0 as libc::c_int;
            }
            if strncmp(
                *argv.offset(1 as libc::c_int as isize),
                b"--execfd=\0" as *const u8 as *const libc::c_char,
                9 as libc::c_int as libc::c_ulong,
            ) == 0 as libc::c_int
            {
                let mut errstr: *const libc::c_char = std::ptr::null::<libc::c_char>();
                cp = (*argv.offset(1 as libc::c_int as isize)).offset(9 as libc::c_int as isize);
                fd = sudo_strtonum(
                    cp,
                    0 as libc::c_int as libc::c_longlong,
                    2147483647 as libc::c_int as libc::c_longlong,
                    &mut errstr,
                ) as libc::c_int;
                if !errstr.is_null() {
                    sudo_debug_printf2_v1(
                        (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"main\0"))
                            .as_ptr(),
                        b"sesh.c\0" as *const u8 as *const libc::c_char,
                        108 as libc::c_int,
                        2 as libc::c_int
                            | (1 as libc::c_int) << 5 as libc::c_int
                            | sudo_debug_subsys,
                        sudo_warn_gettext_v1(
                            std::ptr::null::<libc::c_char>(),
                            b"invalid file descriptor number: %s\0" as *const u8
                                as *const libc::c_char,
                        ),
                        cp,
                    );
                    sudo_fatalx_nodebug_v1(
                        sudo_warn_gettext_v1(
                            std::ptr::null::<libc::c_char>(),
                            b"invalid file descriptor number: %s\0" as *const u8
                                as *const libc::c_char,
                        ),
                        cp,
                    );
                }
                argv = argv.offset(1);
                argc -= 1;
            }
            argv = argv.offset(1);
            argc -= 1;
            cmnd = strdup(*argv.offset(0 as libc::c_int as isize));
            if cmnd.is_null() {
                sudo_debug_printf2_v1(
                    (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"main\0")).as_ptr(),
                    b"sesh.c\0" as *const u8 as *const libc::c_char,
                    117 as libc::c_int,
                    2 as libc::c_int | (1 as libc::c_int) << 5 as libc::c_int | sudo_debug_subsys,
                    sudo_warn_gettext_v1(
                        std::ptr::null::<libc::c_char>(),
                        b"%s: %s\0" as *const u8 as *const libc::c_char,
                    ),
                    (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"main\0")).as_ptr(),
                    sudo_warn_gettext_v1(
                        std::ptr::null::<libc::c_char>(),
                        b"unable to allocate memory\0" as *const u8 as *const libc::c_char,
                    ),
                );
                sudo_fatalx_nodebug_v1(
                    sudo_warn_gettext_v1(
                        std::ptr::null::<libc::c_char>(),
                        b"%s: %s\0" as *const u8 as *const libc::c_char,
                    ),
                    (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"main\0")).as_ptr(),
                    sudo_warn_gettext_v1(
                        std::ptr::null::<libc::c_char>(),
                        b"unable to allocate memory\0" as *const u8 as *const libc::c_char,
                    ),
                );
            }
            if login_shell {
                cp = strrchr(*argv.offset(0 as libc::c_int as isize), '/' as i32);
                if cp.is_null() {
                    sudo_debug_printf2_v1(
                        (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"main\0"))
                            .as_ptr(),
                        b"sesh.c\0" as *const u8 as *const libc::c_char,
                        122 as libc::c_int,
                        2 as libc::c_int
                            | (1 as libc::c_int) << 5 as libc::c_int
                            | (1 as libc::c_int) << 4 as libc::c_int
                            | sudo_debug_subsys,
                        sudo_warn_gettext_v1(
                            std::ptr::null::<libc::c_char>(),
                            b"unable to run %s as a login shell\0" as *const u8
                                as *const libc::c_char,
                        ),
                        *argv.offset(0 as libc::c_int as isize),
                    );
                    sudo_fatal_nodebug_v1(
                        sudo_warn_gettext_v1(
                            std::ptr::null::<libc::c_char>(),
                            b"unable to run %s as a login shell\0" as *const u8
                                as *const libc::c_char,
                        ),
                        *argv.offset(0 as libc::c_int as isize),
                    );
                }
                *cp = '-' as i32 as libc::c_char;
                let fresh0 = &mut *argv.offset(0 as libc::c_int as isize);
                *fresh0 = cp;
            }
            sudo_execve(fd, cmnd, argv as *const *mut libc::c_char, envp, noexec);
            sudo_debug_printf2_v1(
                (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"main\0")).as_ptr(),
                b"sesh.c\0" as *const u8 as *const libc::c_char,
                127 as libc::c_int,
                3 as libc::c_int
                    | (1 as libc::c_int) << 5 as libc::c_int
                    | (1 as libc::c_int) << 4 as libc::c_int
                    | sudo_debug_subsys,
                sudo_warn_gettext_v1(
                    std::ptr::null::<libc::c_char>(),
                    b"unable to execute %s\0" as *const u8 as *const libc::c_char,
                ),
                cmnd,
            );
            sudo_warn_nodebug_v1(
                sudo_warn_gettext_v1(
                    std::ptr::null::<libc::c_char>(),
                    b"unable to execute %s\0" as *const u8 as *const libc::c_char,
                ),
                cmnd,
            );
            ret = 1 as libc::c_int;
        }
        sudo_debug_exit_int_v1(
            (*::core::mem::transmute::<&[u8; 5], &[libc::c_char; 5]>(b"main\0")).as_ptr(),
            b"sesh.c\0" as *const u8 as *const libc::c_char,
            130 as libc::c_int,
            sudo_debug_subsys,
            ret,
        );
        _exit(ret);
    } //unsafe
}

fn sesh_sudoedit(mut argc: libc::c_int, mut argv: *mut *mut libc::c_char) -> libc::c_int {
    let mut i: libc::c_int = 0;
    let mut oflags_src: libc::c_int = 0;
    let mut oflags_dst: libc::c_int = 0;
    let mut post: libc::c_int = 0;
    let mut ret: libc::c_int = 1 as libc::c_int;
    let mut fd_src: libc::c_int = -(1 as libc::c_int);
    let mut fd_dst: libc::c_int = -(1 as libc::c_int);
    let mut follow: libc::c_int = 0 as libc::c_int;
    let mut nread: ssize_t = 0;
    let mut nwritten: ssize_t = 0;

    let mut sb: stat = sb_all_arch;
    let mut times: [timespec; 2] = [timespec {
        tv_sec: 0,
        tv_nsec: 0,
    }; 2];
    let mut buf: [libc::c_char; 8192] = [0; 8192];

    unsafe {
        debug_decl!(SUDO_DEBUG_EDIT);

        if strcmp(
            *argv.offset(2 as libc::c_int as isize),
            b"-h\0" as *const u8 as *const libc::c_char,
        ) == 0 as libc::c_int
        {
            argv = argv.offset(1);
            argc -= 1;
            follow = 0o400000 as libc::c_int;
        }

        if argc < 3 {
            debug_return_int!(1);
        }

        if strcmp(
            *argv.offset(2 as libc::c_int as isize),
            b"0\0" as *const u8 as *const libc::c_char,
        ) == 0 as libc::c_int
        {
            post = 0;
        } else if strcmp(
            *argv.offset(2 as libc::c_int as isize),
            b"0\0" as *const u8 as *const libc::c_char,
        ) == 0 as libc::c_int
        {
            post = 1;
        } else {
            debug_return_int!(30);
        }

        argv = argv.offset(3 as libc::c_int as isize);
        argc -= 3 as libc::c_int;

        if argc == 0 {
            debug_return_int!(0);
        }

        if argc & 1 != 0 {
            debug_return_int!(31);
        }

        oflags_src = 0 as libc::c_int
            | (if post != 0 {
                0o4000 as libc::c_int | 0o400000 as libc::c_int
            } else {
                follow
            });

        oflags_dst = 0o1 as libc::c_int
            | 0o100 as libc::c_int
            | (if post != 0 {
                follow
            } else {
                0o200 as libc::c_int
            });

        //start goto
        'cleanup_0: loop {
            'nocleanup: loop {
                //for
                i = 0;
                loop {
                    if i >= argc - 1 {
                        break;
                    }

                    let mut path_src: *const libc::c_char = *argv.offset(i as isize);
                    let mut path_dst: *const libc::c_char =
                        *argv.offset((i + 1 as libc::c_int) as isize);

                    fd_src = open(
                        path_src,
                        oflags_src,
                        0o400 as libc::c_int | 0o200 as libc::c_int,
                    );
                    if fd_src < 0 && *__errno_location() != 2 {
                        //define sudo_warn("%s",path_src);
                        sudo_debug_printf!(
                            SUDO_DEBUG_WARN | SUDO_DEBUG_LINENO | SUDO_DEBUG_ERRNO,
                            b"%s\0" as *const u8 as *const libc::c_char,
                            path_src
                        );
                        sudo_warn_nodebug_v1(b"%s\0" as *const u8 as *const libc::c_char, path_src);
                        //end of define;

                        if post != 0 {
                            ret = 33;
                            break 'nocleanup;
                        }
                        //end of post != 0
                        else {
                            break 'cleanup_0;
                        }
                    } //end of "if fd_src < 0"

                    /*if fd_src < 0 {
                        if *__errno_location() != 2 {
                            //define sudo_warn("%s",path_src);
                            sudo_debug_printf!(
                                SUDO_DEBUG_WARN | SUDO_DEBUG_LINENO | SUDO_DEBUG_ERRNO,
                                b"%s\0" as *const u8 as *const libc::c_char,
                                path_src
                            );
                            sudo_warn_nodebug_v1(
                                b"%s\0" as *const u8 as *const libc::c_char,
                                path_src,
                            );
                            //end of define;

                            if post != 0 {
                                ret = 33;
                                break 'nocleanup;
                            }
                            //end of post != 0
                            else {
                                break 'cleanup_0;
                            }
                        } //end of __errno_location
                    }*/
                    //end of "if fd_src < 0"

                    if post != 0 {
                        if !sudo_check_temp_file(fd_src, path_src, geteuid(), &mut sb) {
                            ret = 33;
                            break 'nocleanup;
                        }
                        fcntl(
                            fd_src,
                            4 as libc::c_int,
                            fcntl(fd_src, 3 as libc::c_int, 0 as libc::c_int)
                                & !(0o4000 as libc::c_int),
                        );
                    }

                    fd_dst = open(
                        path_dst,
                        oflags_dst,
                        if post != 0 {
                            0o400 as libc::c_int
                                | 0o200 as libc::c_int
                                | 0o400 as libc::c_int >> 3 as libc::c_int
                                | 0o400 as libc::c_int >> 3 as libc::c_int >> 3 as libc::c_int
                        } else {
                            0o400 as libc::c_int | 0o200 as libc::c_int
                        },
                    );
                    if fd_dst < 0 {
                        //define sudo_warn("%s",path_dst);
                        sudo_debug_printf!(
                            SUDO_DEBUG_WARN | SUDO_DEBUG_LINENO | SUDO_DEBUG_ERRNO,
                            b"%s\0" as *const u8 as *const libc::c_char,
                            path_dst
                        );
                        sudo_warn_nodebug_v1(b"%s\0" as *const u8 as *const libc::c_char, path_dst);
                        //end of define;
                        if post != 0 {
                            ret = 33;
                            break 'nocleanup;
                        } else {
                            break 'cleanup_0;
                        }
                    }

                    if fd_src != -1 {
                        let mut len_src: off_t = -(1 as libc::c_int) as off_t;
                        let mut len_dst: off_t = -(1 as libc::c_int) as off_t;
                        if post != 0 {
                            len_src = sb.st_size;
                            if fstat(fd_dst, &mut sb) != 0 as libc::c_int {
                                ret = 33;
                                break 'nocleanup;
                            }
                            len_dst = sb.st_size;
                        }

                        if sudo_copy_file(path_src, fd_src, len_src, path_dst, fd_dst, len_dst)
                            == -1
                        {
                            if post != 0 {
                                ret = 33;
                                break 'nocleanup;
                            } else {
                                break 'cleanup_0;
                            }
                        }
                    } //end of fd_src != -1

                    if post == 0 {
                        if fd_src == -1 || fstat(fd_src, &mut sb) != 0 {
                            memset(
                                &mut sb as *mut stat as *mut libc::c_void,
                                0 as libc::c_int,
                                ::std::mem::size_of::<stat>() as libc::c_ulong,
                            );
                        }
                        times[0 as libc::c_int as usize].tv_sec = sb.st_mtim.tv_sec;
                        times[0 as libc::c_int as usize].tv_nsec = sb.st_mtim.tv_nsec;
                        times[1 as libc::c_int as usize].tv_sec =
                            times[0 as libc::c_int as usize].tv_sec;
                        times[1 as libc::c_int as usize].tv_nsec =
                            times[0 as libc::c_int as usize].tv_nsec;

                        if futimens(fd_dst, times.as_mut_ptr() as *const timespec) == -1
                            && utimensat(-100, path_dst, times.as_mut_ptr() as *const timespec, 0)
                                == -1
                        {
                            //define sudo_warn("%s",path_dst);
                            sudo_debug_printf!(
                                SUDO_DEBUG_WARN | SUDO_DEBUG_LINENO | SUDO_DEBUG_ERRNO,
                                b"%s\0" as *const u8 as *const libc::c_char,
                                path_dst
                            );
                            sudo_warn_nodebug_v1(
                                b"%s\0" as *const u8 as *const libc::c_char,
                                path_dst,
                            );
                            //end of define;
                        }

                        /*if futimens(fd_dst, times.as_mut_ptr() as *const timespec) == -1 {
                            if utimensat(-100, path_dst, times.as_mut_ptr() as *const timespec, 0)
                                == -1
                            {
                                //define sudo_warn("%s",path_dst);
                                sudo_debug_printf!(
                                    SUDO_DEBUG_WARN | SUDO_DEBUG_LINENO | SUDO_DEBUG_ERRNO,
                                    b"%s\0" as *const u8 as *const libc::c_char,
                                    path_dst
                                );
                                sudo_warn_nodebug_v1(
                                    b"%s\0" as *const u8 as *const libc::c_char,
                                    path_dst,
                                );
                                //end of define;
                            }
                        }*/
                    } //end of post==0

                    close(fd_dst);
                    fd_dst = -1;
                    if fd_src != -1 {
                        close(fd_src);
                        fd_src = -1;
                    }

                    i += 2;
                } //end of loop ,same as for

                //line 294
                ret = 0;
                if post != 0 {
                    i = 0 as libc::c_int;
                    while i < argc - 1 as libc::c_int {
                        unlink(*argv.offset(i as isize));
                        i += 2 as libc::c_int;
                    }
                }

                break 'nocleanup;
            } //end of nocleanup
            if fd_dst != -1 {
                close(fd_dst);
            }
            if fd_src != -1 {
                close(fd_src);
            }
            return ret;

            break 'cleanup_0;
        } //end of cleanup_0
        i = 0;
        while i < argc - 1 as libc::c_int {
            unlink(*argv.offset((i + 1 as libc::c_int) as isize));
            i += 2;
        }
        if fd_dst != -1 {
            close(fd_dst);
        }
        if fd_src != -1 {
            close(fd_src);
        }
    } //unsafe
    32
} //end of function

pub fn main() {
    let mut args: Vec<*mut libc::c_char> = Vec::new();
    for arg in ::std::env::args() {
        args.push(
            (::std::ffi::CString::new(arg))
                .expect("Failed to convert argument into CString.")
                .into_raw(),
        );
    }
    args.push(::std::ptr::null_mut());
    let mut vars: Vec<*mut libc::c_char> = Vec::new();
    for (var_name, var_value) in ::std::env::vars() {
        let var: String = format!("{}={}", var_name, var_value);
        vars.push(
            (::std::ffi::CString::new(var))
                .expect("Failed to convert environment variable into CString.")
                .into_raw(),
        );
    }
    vars.push(::std::ptr::null_mut());
    //unsafe {
    ::std::process::exit(main_0(
        (args.len() - 1) as libc::c_int,
        args.as_mut_ptr(),
        vars.as_mut_ptr(),
    ) as i32)
    //}
}
